package com.ftg.learn.mybatis.chapter3.mapper;

import com.ftg.learn.mybatis.chapter3.entity.Sale;
import com.ftg.learn.mybatis.chapter3.vo.SaleAndFramer;
import com.ftg.learn.mybatis.chapter3.vo.SaleDetail;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 用来做为我们的mybatis的映射器类
 *    替换原来的sale.xml
 *    面向接口编程
 *
 *    SaleMapper 相当于chapter2当中的 dao包里面的 saleDao sale.xml
 *    用一个接口完成两个部分的替换
 *
 * 接口开发模式 由于底层使用的是反射方式，所以在声明方法时，不允许使用重载
 *   方法相同，参数不同，mappedStatement里存储时用的是方法名称做为key
 *
 * @author kangjx
 * @date 2022/10/13
 */
@SuppressWarnings("all")
public interface SaleMapper {

    /**
     * 用来查看全部sale表信息的方法
     * @return List<Sale>
     */
    @Select(value = "select id, name, address, fid, unit, price, type, scdate, ccdate from sale where flag = 0")
    List<Sale> showall();

    /**
     * 带参查询
     *  多个参数时要用 :
     *      默认 ： 第一个参数 arg0|param1 第二个叫 arg1 | param2 依次类推  本人不推荐
     *      mybatis注解方式： @param(绑定参数) 强烈推荐
     * @param id   主键
     * @param name 名称
     * @return List<Sale>
     */
    @Select("select id, name, address, fid, unit, price, type, scdate, ccdate from sale" +
            " where id=#{id} and name like concat(#{name},'%') and flag = 0")
    List<Sale> showallWithPara(@Param(value="id") Integer id, @Param("name") String name);

    /**
     * 完成商品添加功能
     * @param sale 部门信息
     * @return  int
     */
    @Insert("insert into sale(name, address, fid, unit, price, type)" +
            " values(#{name},#{address},#{fid},#{unit},#{price},#{type})")
    int saveSale(Sale sale);

    /**
     * 根据传递过来的id(老的主键)，进行修改
     * @param sale  商品的最新信息
     * @param id    商品原始主键
     * @return  int
     */
    @Update("UPDATE sale SET id=#{sale.id},name=#{sale.name},address=#{sale.address}" +
            ",fid=#{sale.fid},unit=#{sale.unit},price=#{sale.price},type=#{sale.type}" +
            " where id = #{id} and falg = 0")
    int updateSale(@Param("sale") Sale sale,@Param("id") long id);

    /**
     * 按主键进行删除操作
     * @param id  主键
     * @return  int
     */
    @Delete("delete from sale where id = #{id}")
    int delSale(@Param("id") long id);


    /**
     * 按主键进行删除操作
     * @param id  主键
     * @return  int
     */
    @Update("update sale set flag = 1 where id = #{id}")
    int delSaleLogic(@Param("id") long id);

    /**
     * 连表查询操作
     * @return List<SaleDetail>
     */
    @Select(value = "select " +
            "        s.id, s.name, s.address, fid, unit, price, s.type, scdate, ccdate " +
            "        ,sf.name fname,sf.address faddress,sf.boss,sf.type ftype " +
            "        from sale s left join saleframer sf on s.fid = sf.id " +
            "        where s.id = #{id} and flag = 0")
    List<SaleDetail> showSaleDetail();

    /**
     * 两套思路 完成基于注解的动态sql开发模式
     */

    /**
     * <script> </script> 完成我们sql动记sql，可以像xml一样开发sql
     * <where></where>
     * <if></if>
     * <choose></choose>
     * @return List<Sale>
     */
    @Select("<script>" +
                "select id, name, address, fid, unit, price, type, scdate, ccdate from sale " +
                "<where>" +
                    "<if test=\"id != null\">" +
                        " and id = #{id}" +
                    "</if>" +
                    "<if test=\"name != null\">" +
                        " and name = concat(#{id},'%')" +
                    "</if>" +
                   " and flag = 0"+
                "</where>" +
            "</script>")
    List<Sale> select1WithDyname(@Param("id")Long id,@Param("name") String name);

    /**
     * 使用查询向导，通过纯java返回sql语句
     * @param id 主键
     * @param name 名称
     */
    @SelectProvider(value=SaleProvider.class,method = "createSqlBySelect2WithDyname")
    List<Sale> select2WithDyname(@Param("id")Long id,@Param("name") String name);

    /**
     * 使用查询向导引导到指定的类，通过构建器返回sql语句
     * @param id 主键
     * @param name 名称
     */
    @SelectProvider(value=SaleProvider.class,method = "createSqlBySelect2WithDyname1")
    List<Sale> select3WithDyname(@Param("id")Long id,@Param("name") String name);

    //除我们的级联操作没有写以外，其它的常见方法全部讲完了

    /**
     * 通过农场的编号查询当前农场的所有商品
     * @param fid  农场的id
     * @return List<Sale>
     */
    @Select("select id, name, address, fid, unit, price, type, scdate, ccdate from sale where flag = 0 and fid = #{fid}")
    List<Sale> selectByFid(@Param("fid") Long fid);

    /**
     * 级联操作，用过商品 连带查询出来农场信息
     * @return List<SaleAndFramer></SaleAndFramer>
     */
    @Select("select id, name, address, fid, unit, price, type, scdate, ccdate from sale where flag = 0")
    @Results({
        @Result(column = "fid",property = "fid"),
        @Result(column = "fid",property = "saleFramer",one = @One(select = "com.ftg.learn.mybatis.chapter3.mapper.SaleFramerMapper.findById"))
    })
    List<SaleAndFramer>  showSaleInfoWithFramer();
}
